package br.com.jmed.control;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;

import javax.annotation.Resource;
import javax.el.MethodExpression;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperRunManager;
import br.com.jmed.model.Usuario;

public class BaseControl {

	private boolean cadastroOk = false;
	
	protected static final String URL_DIRETORIO_RELATORIOS = "/Users/felipe";
	
	@ManagedProperty(value="#{segurancaControl}")
	private SegurancaControl segurancaControl;
	
	@Resource(name="java:/jdbc/jMedDS")	
	private DataSource dataSource;
	
	public MethodExpression createMethodExpression(String action) {
		MethodExpression methodExpression = FacesContext
				.getCurrentInstance()
				.getApplication()
				.getExpressionFactory()
				.createMethodExpression(
						FacesContext.getCurrentInstance().getELContext(),
						action, null, new Class<?>[0]);
		return methodExpression;
	}
	
	public Connection getConnection() throws Exception {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			throw new Exception("Erro ao solicitar conexão para o relatório.");
		}
	}
	
	public void gerarRelatorio(String nomeArquivo, Map<String,Object> parametros) throws Exception{
		
		byte[] bytes = null;
		ServletOutputStream ouputStream = null;
		parametros.put("REPORT_CONNECTION", getConnection());
		File arquivo = new File(URL_DIRETORIO_RELATORIOS+"/"+nomeArquivo+".jasper");
		
		if(!arquivo.exists()){
			throw new Exception("Arquivo não encontrato. ("+nomeArquivo+")");
		}
		
        try {
			bytes = JasperRunManager.runReportToPdf(arquivo.getPath(), parametros);
		} catch (JRException e) {
			throw new Exception("Erro ao gerar o relatório.");
		}

        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
        
        if (bytes != null && bytes.length > 0) {
            
        	response.setContentType("application/pdf");
            response.setContentLength(bytes.length);
            response.setHeader("Content-Disposition", "attachment; filename="+arquivo.getName()+".pdf");
            
            try {
				ouputStream = response.getOutputStream();
				ouputStream.write(bytes, 0, bytes.length);
	            ouputStream.flush();
	            ouputStream.close();
	            FacesContext.getCurrentInstance().responseComplete();
            } catch (IOException e) {
            	throw new Exception("Erro ao enviar o relatório.");
            }
            
        }
	}
	
	public boolean isCadastroOk() {
		return cadastroOk;
	}

	public Usuario getUsuario(){
		return segurancaControl.getUsuario();
	}
	
	public void createFormMessage(String componentId,String message){
		FacesContext.getCurrentInstance().addMessage(componentId,new FacesMessage(message));
	}
	
	public void createFormMessage(String componentId,FacesMessage message){
		FacesContext.getCurrentInstance().addMessage(componentId,message);
	}
	
	public void setCadastroOk(boolean cadastroOk) {
		this.cadastroOk = cadastroOk;
	}
	
	public void redirect(String url) throws IOException {
		FacesContext.getCurrentInstance().getExternalContext().redirect(url);
	}
	
	public void setDataSource(DataSource dataSource){
		this.dataSource = dataSource;
	}
	
	public void setSegurancaControl(SegurancaControl segurancaControl) {
		this.segurancaControl = segurancaControl;
	}	

}
